jetcrab\bytecode\statements/
function.rs

1use crate::ast::Node;
2use crate::vm::instructions::Instruction;
3
4pub trait FunctionGenerator {
5    fn generate_function_declaration(&mut self, node: &Node);
6    fn generate_function_expression(&mut self, node: &Node);
7}
8
9pub trait FunctionCore {
10    fn instructions(&mut self) -> &mut Vec<Instruction>;
11    fn visit_node(&mut self, node: &Node);
12}
13
14impl<T> FunctionGenerator for T
15where
16    T: FunctionCore + crate::bytecode::scope::constants::ConstantManager,
17{
18    fn generate_function_declaration(&mut self, node: &Node) {
19        if let Node::FunctionDeclaration(decl) = node {
20            // For now, implement a simplified version
21            // Store function name as a special constant
22            if let Some(id) = &decl.id {
23                if let Node::Identifier(name) = &**id {
24                    // Create a special function identifier
25                    let function_id = self.add_constant(format!("__FUNCTION_{}", name));
26                    self.instructions()
27                        .push(Instruction::PushConst(function_id));
28
29                    // Store the function in global scope (for now, just push it)
30                    // TODO: Implement proper global variable storage
31                    self.instructions().push(Instruction::PushUndefined);
32                }
33            }
34
35            // Generate function body for later execution
36            self.visit_node(&decl.body);
37        }
38    }
39
40    fn generate_function_expression(&mut self, node: &Node) {
41        if let Node::FunctionExpression(expr) = node {
42            // For now, implement a simplified version
43            // Generate function body
44            self.visit_node(&expr.body);
45
46            // Store the function as a callable function
47            // We'll use a special constant to mark this as a function
48            let function_id = format!(
49                "__FUNCTION_EXPR_{}",
50                expr.id.as_ref().map(|_id| "named").unwrap_or("anonymous")
51            );
52            let constant_index = self.add_constant(function_id);
53            self.instructions()
54                .push(Instruction::PushConst(constant_index));
55        }
56    }
57}